/*
 * EpikSocket.cpp
 *
 *  Created on: Jul 31, 2010
 *      Author: Justin
 */
#include "Epik_Socket.h"
#include <pspkernel.h>
#include <pspsdk.h>
#include <stdlib.h>
#include <cstring>
#include <unistd.h>
#include <pspnet.h>
#include <pspnet_inet.h>
#include <pspnet_apctl.h>
#include <pspnet_resolver.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <errno.h>

#ifdef EPIK_DEBUG
#include <pspdebug.h>
#endif

const char Socket::NEWLINE_ = '\n';

Socket::Socket(char *addr, uint16_t p)
	:port_(p)
{
	int ret;
	tv_.tv_sec = 0;
	tv_.tv_usec = 25000;

	sock_ = socket(AF_INET, SOCK_STREAM, 0);
#ifdef EPIK_DEBUG
	if(sock_<0)
	{
		pspDebugScreenPrintf("Error creating socket.");
//		sceKernelExitGame();
	}
	else
	{
		pspDebugScreenPrintf("Socket successfully created (%d).\n", sock_);
	}
#endif

	servAddr_.sin_len = sizeof(servAddr_);
	servAddr_.sin_family = AF_INET;
#ifdef EPIK_DEBUG
	pspDebugScreenPrintf("sin_family set to AF_INET (%d=%d)\n", AF_INET, servAddr_.sin_family);
#endif
	servAddr_.sin_port = htons(port_);
#ifdef EPIK_DEBUG
	pspDebugScreenPrintf("sin_port set to %d (%X=%X)\n", port_, htons(port_), servAddr_.sin_port);
#endif
	inet_pton(AF_INET, addr, &servAddr_.sin_addr);

	ret = connect(sock_, (sockaddr *)&servAddr_, sizeof(servAddr_));
#ifdef EPIK_DEBUG
	if( ret==0 )
		pspDebugScreenPrintf("Successfully connected to server.\n");
	else
		pspDebugScreenPrintf("Error while connecting (%d).\n", ret);
#endif
/*
	// Setting delay on thread read/write
	timeval tv;
	tv.tv_sec = 0;
	tv.tv_usec = 10000;
	setsockopt(sock_, IP_OPTIONS, SO_RCVTIMEO, (void *)&tv, sizeof(tv));
	setsockopt(sock_, IP_OPTIONS, SO_SNDTIMEO, (void *)&tv, sizeof(tv));
*/
#ifdef EPIK_DEBUG
	sceKernelDelayThread(10000);
	pspDebugScreenClear();
#endif
};



Socket::~Socket()
{
	sceNetInetClose(sock_);
}



void Socket::Send(const char *msg) const
{
//	pspDebugScreenPrintf("SENDING\t%s", msg);
	int ret = send(sock_, (void *)msg, strlen(msg), 0);
#ifdef EPIK_DEBUG
	if (ret != 0)
		pspDebugScreenPrintf("send() returned %d.\n", ret);
#endif
}

void Socket::SendLine(const char *msg) const
{
	char *line = new char[sizeof(msg)+2];	// 2 instead of 1 JiC
	strcpy(line,msg);
	strcat(line, "\n");
	int ret = send(sock_, (void *)line, strlen(line), 0);
	// message send
#ifdef EPIK_DEBUG
	if (ret <0 || ret != strlen(line))
		pspDebugScreenPrintf("ERR\tSend() returned %d.\n", ret);
/*
	// message send
	int ret = send(sock_, (void *)msg, strlen(msg), 0);
	if (ret != 0)
		pspDebugScreenPrintf("send() returned %d.\n", ret);

	// line break
	ret = send(sock_, (void *)&NEWLINE_, 1, 0);
//	if (ret != 0)
//		pspDebugScreenPrintf("send() returned %d.\n", ret);
*/
#endif
}



int Socket::Recv(char *buf, u16 size) const
{
//	pspDebugScreenPrintf("Attempting to create \"rfds\"...");
	fd_set rfds;
	FD_ZERO(&rfds);
	FD_SET(0, &rfds);
//	pspDebugScreenPrintf("Done!\n");

//	pspDebugScreenPrintf("Running \"select()\"...");
	int retval = select(1, &rfds, NULL, NULL, const_cast<timeval*>(&tv_));
//	pspDebugScreenPrintf("Done!\n");
	if (retval == -1)
	{
		// Error
	}
	else if (retval)
	{
		// Read Socket
	}
	else
	{
		// Nothing to read...
	}

	return 0;
}



int Socket::GetMacAddr(unsigned char mac[4]) const
{
	return sceNetGetLocalEtherAddr(mac);
}

